//
//  MWPhoto.m
//  MWPhotoBrowser
//
//  Created by Michael Waterfall on 17/10/2010.
//  Copyright 2010 d3i. All rights reserved.
//

#import "MWPhoto.h"
#import "MWPhotoBrowser.h"
// Private
@interface MWPhoto () {

    // Image Sources
    NSString *_photoPath;
    NSURL *_photoURL;

    NSURL *_previewPhotoURL;
    
    // Image
    UIImage *_underlyingImage;

    // Other
    NSString *_caption;
}

// Properties
@property (nonatomic, retain) UIImage *underlyingImage;
@property (nonatomic, retain) NSURL *previewPhotoURL;
@property (nonatomic, retain) NSURL *originalPhotoURL;

@property (nonatomic, assign) CGSize targetSize;

// Methods
- (void)imageDidFinishLoadingSoDecompress;
- (void)imageLoadingComplete;

@end

// MWPhoto
@implementation MWPhoto

// Properties
@synthesize underlyingImage = _underlyingImage, 
caption = _caption,
previewPhotoURL = _previewPhotoURL;
@synthesize downloadProgress, disableZooming;
@synthesize loadingInProgress;

#pragma mark Class Methods

+ (MWPhoto *)photoWithImage:(UIImage *)image {
	return [[[MWPhoto alloc] initWithImage:image] autorelease];
}

+ (MWPhoto *)photoWithFilePath:(NSString *)path {
	return [[[MWPhoto alloc] initWithFilePath:path] autorelease];
}

+ (MWPhoto *)photoWithURL:(NSURL *)url {
	return [[[MWPhoto alloc] initWithURL:url] autorelease];
}

+ (MWPhoto *)photoWithText:(NSString*) txt{
    return [[[MWPhoto alloc] initWithText:txt] autorelease];
}

+ (MWPhoto *)photoWithURL:(NSURL *)url previewImageUrl:(NSURL*)preUrl originalImageUrl:(NSURL *)originalUrl{
	return [[[MWPhoto alloc] initWithURL:url previewImageUrl:preUrl originalImageUrl:originalUrl] autorelease];
}

+ (MWPhoto *)photoWithPHAsset:(PHAsset *)asset targetSize:(CGSize)size
{
    return [[[MWPhoto alloc] initWithPHAsset:asset targetSize:size] autorelease];
}

#pragma mark NSObject

- (id)initWithImage:(UIImage *)image {
	if ((self = [super init])) {
		self.underlyingImage = image;
	}
	return self;
}

- (id)initWithFilePath:(NSString *)path {
	if ((self = [super init])) {
		_photoPath = [path copy];
	}
	return self;
}

- (id)initWithURL:(NSURL *)url {
	if ((self = [super init])) {
		_photoURL = [url copy];
	}
	return self;
}

- (id)initWithURL:(NSURL *)url previewImageUrl:(NSURL*)preUrl originalImageUrl:(NSURL *)originalUrl{
	if ((self = [super init])) {
		_photoURL = [url copy];
        self.previewPhotoURL = preUrl;
        _originalPhotoURL = [originalUrl copy];
	}
	return self;
}

- (id)initWithText:(NSString*)txt
{
    if ((self = [super init])) {
		//self.underlyingImage = [Utility imageFromText:txt];
        disableZooming = YES;
	}
	return self;
}

- (id)initWithPHAsset:(PHAsset *)asset targetSize:(CGSize)size
{
    self = [super init];
    if (self) {
        self.asset = asset;
        self.targetSize = size;
        
    }
    return self;
}

- (void)dealloc {
    [_asset release];
    [_caption release];
    [[SDWebImageManager sharedManager] cancelForDelegate:self];
	[_photoPath release];
	[_photoURL release];
	[_underlyingImage release];
    [_previewPhotoURL release];
    [_originalPhotoURL release];
    [downloadProgress release];
	[super dealloc];
}

#pragma mark MWPhoto Protocol Methods

- (NSURL *)previewPhotoURL {
    return _previewPhotoURL;
}

- (UIImage *)underlyingImage {
    return _underlyingImage;
}

- (MWPhotoType)getCurrentPhotoType{
    return _currentPhotoType;
}

- (BOOL)isLoadingInProgress {
    return self.loadingInProgress;
}

-  (void)loadUnderlyingImageWithPhotoType:(MWPhotoType)photoType
{
    NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
  
    if (self.asset) {
        self.loadingInProgress = YES;
        if (self.underlyingImage)
        {
            [self imageLoadingComplete];
            return;
        }
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        NSDictionary *userInfo = @{@"targetSize":[NSValue valueWithCGSize:self.targetSize]};
        [manager downloadWithPHAsset:self.asset delegate:self options:SDWebImageCacheMemoryOnly userInfo:userInfo];
    } else if (self.underlyingImage && (_currentPhotoType >= photoType)) {
        // Image already loaded in memory;
       
        [self imageLoadingComplete];
    } else if (_photoPath) {
        // Load async from file
        [self performSelectorInBackground:@selector(loadImageFromFileAsync) withObject:nil];
    } else {
        // Load async from web (using SDWebImage)
        // if bigger image was already cached in disk or memory, use the cached image directly
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        UIImage *cachedImage = [manager imageWithURL:_photoURL];
        UIImage *cachedPreviewImage = [manager imageWithURL:_previewPhotoURL];
        UIImage *cachedOriginalImage = [manager imageWithURL:_originalPhotoURL];
        
        if (cachedOriginalImage) {
            // Use the cached image immediatly
            self.underlyingImage = cachedOriginalImage;
            _currentPhotoType = MWPhotoOriginal;
            [self imageDidFinishLoadingSoDecompress];
        } else if (cachedImage && photoType != MWPhotoOriginal) {
            // Use the cached image immediatly
            self.underlyingImage = cachedImage;
            _currentPhotoType = MWPhotoNormal;
            [self imageDidFinishLoadingSoDecompress];
        } else if (cachedPreviewImage && photoType == MWPhotoMini) {
            // Use the cached image immediatly
            self.underlyingImage = cachedPreviewImage;
            _currentPhotoType = MWPhotoMini;
            [self imageDidFinishLoadingSoDecompress];
        } else {
            // Start an async download
            NSURL *tempUrl = nil;
            switch (photoType) {
                case MWPhotoMini:
                    tempUrl = _previewPhotoURL;
                    break;
                case MWPhotoNormal:
                    tempUrl = _photoURL;
                    break;
                case MWPhotoOriginal:
                    tempUrl = _originalPhotoURL;
                    break;
                    
                default:
                    break;
            }
            
            // ZHY: for location image, no original or mini image url
            tempUrl = tempUrl ? tempUrl : _photoURL;
            
            if (!tempUrl) {
#ifdef ZHY_DEBUG
//                NSAssert(0, @"Image url should not be nil %d", photoType);
#endif
                // Failed - no source
//                self.underlyingImage = nil;
                [self imageLoadingComplete];
            } else {
                [manager downloadWithURL:tempUrl delegate:self options:0 success:^(UIImage *image, BOOL cached) {
                    _currentPhotoType = photoType;
                } failure:^(NSError *error) {
                }];
            }
        }
    }
}

//- (void)loadUnderlyingImageAndNotify {
//    NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
//    _loadingInProgress = YES;
//    
//    OntheRoadAppDelegate * appDele = appDelegate;
//    
//    if (self.underlyingImage) {
//        // Image already loaded
//        [self imageLoadingComplete];
//    } else {
//        if (_photoPath) {
//            // Load async from file
//            [self performSelectorInBackground:@selector(loadImageFromFileAsync) withObject:nil];
//        }else if(_photoURL && _previewPhotoURL){
//            // Load async from web (using SDWebImage)
//            SDWebImageManager *manager = [SDWebImageManager sharedManager];
//            UIImage *cachedImage = [manager imageWithURL:_photoURL];
//            UIImage *cachedPreviewImage = [manager imageWithURL:_previewPhotoURL];
//            if (cachedImage) {
//                // Use the cached image immediatly
//                self.underlyingImage = cachedImage;
//                self.isUnderlyingMiniImage = NO;
//                [self imageDidFinishLoadingSoDecompress];
//            } else if(!(appDele.appMode == QWAppSaveFeeMode) ){
//                // Start an async download
//                [manager downloadWithURL:_photoURL delegate:self options:0 success:^(UIImage *image, BOOL cached) {
//                    self.isUnderlyingMiniImage = NO;
//                } failure:^(NSError *error) {
//                }];
//            } else {
//                //Minimode use preview Image first
//                if (cachedPreviewImage) {
//                    self.underlyingImage = cachedPreviewImage;
//                    self.isUnderlyingMiniImage = YES;
//                    [self imageDidFinishLoadingSoDecompress];
//                }else {
//                    [manager downloadWithURL:_previewPhotoURL delegate:self options:0 success:^(UIImage *image, BOOL cached) {
//                        self.isUnderlyingMiniImage = YES;
//                    } failure:^(NSError *error) {
//                    }];
//                }
//            }
//        }
//        
//        else if (_photoURL && !_previewPhotoURL) {
//            // Load async from web (using SDWebImage)
//            SDWebImageManager *manager = [SDWebImageManager sharedManager];
//            UIImage *cachedImage = [manager imageWithURL:_photoURL];
//            if (cachedImage) {
//                // Use the cached image immediatly
//                self.underlyingImage = cachedImage;
//                [self imageDidFinishLoadingSoDecompress];
//            } else {
//                // Start an async download
//                [manager downloadWithURL:_photoURL delegate:self];
//            }
//        }
//         
//        else {
//            // Failed - no source
//            self.underlyingImage = nil;
//            [self imageLoadingComplete];
//        }
//    }
//}

// Release if we can get it again from path or url
- (void)unloadUnderlyingImage {
    
    _currentPhotoType = MWPhotoNull;
    [[SDWebImageManager sharedManager] cancelForDelegate:self];
	if (self.underlyingImage && (_photoPath || _photoURL)) {
		self.underlyingImage = nil;
	}
    self.loadingInProgress = NO;
}

- (void)loadUnderlyingImageAndNotifyWithHDImage:(BOOL)needHDImage
{
    MWPhotoType type = MWPhotoNormal;
    if (needHDImage) {
        type = MWPhotoOriginal;
    }
    
    [self loadUnderlyingImageWithPhotoType:type];
}



#pragma mark - Async Loading

// Called in background
// Load image in background from local file
- (void)loadImageFromFileAsync {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    @try {
        NSError *error = nil;
        NSData *data = [NSData dataWithContentsOfFile:_photoPath options:NSDataReadingUncached error:&error];
        if (!error) {
            self.underlyingImage = [[[UIImage alloc] initWithData:data] autorelease];
        } else {
            self.underlyingImage = nil;
            MWLog(@"Photo from file error: %@", error);
        }
    } @catch (NSException *exception) {
    } @finally {
        [self performSelectorOnMainThread:@selector(imageDidFinishLoadingSoDecompress) withObject:nil waitUntilDone:NO];
        [pool drain];
    }
}

// Called on main
- (void)imageDidFinishLoadingSoDecompress {
    NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
    // PHAsset拿到的image不需要解码
    if (self.underlyingImage && !self.asset) {
        // Decode image async to avoid lagging when UIKit lazy loads
        [[SDWebImageDecoder sharedImageDecoder] decodeImage:self.underlyingImage withDelegate:self userInfo:nil];
    } else {
        // Failed
        [self imageLoadingComplete];
    }
}

- (void)imageLoadingComplete {
    NSAssert([[NSThread currentThread] isMainThread], @"This method must be called on the main thread.");
    // Complete so notify
    self.loadingInProgress = NO;
    [[NSNotificationCenter defaultCenter] postNotificationName:MWPHOTO_LOADING_DID_END_NOTIFICATION
                                                        object:self];
}

#pragma mark - SDWebImage Delegate

// Called on main
- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image {
    self.underlyingImage = image;
    [self imageDidFinishLoadingSoDecompress];
}

// Called on main
- (void)webImageManager:(SDWebImageManager *)imageManager didFailWithError:(NSError *)error {
    self.underlyingImage = nil;
    MWLog(@"SDWebImage failed to download image: %@", error);
    [self imageDidFinishLoadingSoDecompress];
}

// Called on main
- (void)imageDecoder:(SDWebImageDecoder *)decoder didFinishDecodingImage:(UIImage *)image userInfo:(NSDictionary *)userInfo {
    // Finished compression so we're complete
    self.underlyingImage = image;
    [self imageLoadingComplete];
}

//add by Eric
//Called on Main
- (void)webImageManager:(SDWebImageManager *)imageManager didProgress:(double) progress forURL:(NSURL *)url;
{
//    NSLog(@"progress: %f", progress);
    self.downloadProgress = [NSNumber numberWithDouble:progress];
//    DebugLog(@"previewURL: %@, fullImageURL: %@",_previewPhotoURL, _photoURL);
}
- (BOOL)currentPhotoIsHD
{
    if (_currentPhotoType == MWPhotoOriginal) {
        return YES;
    }
    
    return NO;
}

@end
